// src/composables/useIndexedDB.js
import { reactive, ref, watchEffect } from 'vue'

/**
 * IndexedDB 封装库
 * 提供完整的数据库管理、索引验证和错误恢复功能
 */
export function useIndexedDB(dbName = 'vue3-indexedDB', version = 1, stores = {}) {
  const db = ref(null)
  const isConnected = ref(false)
  const error = ref(null)
  const isInitializing = ref(false)
  let pendingInitPromise = null

  // 存储配置快照，用于版本升级检查
  const configSnapshot = reactive({
    version,
    stores: JSON.stringify(stores)
  })

  // 初始化数据库连接
  const initializeDB = () => {
    if (isConnected.value) return Promise.resolve(db.value)
    if (isInitializing.value) return pendingInitPromise

    isInitializing.value = true
    pendingInitPromise = new Promise((resolve, reject) => {
      console.log(`[IndexedDB] 尝试连接数据库: ${dbName} (版本 ${version})`)

      const request = indexedDB.open(dbName, version)

      // 数据库升级时创建或更新存储和索引
      request.onupgradeneeded = (event) => {
        const db = event.target.result
        console.log(`[IndexedDB] 数据库升级: ${dbName} (${event.oldVersion} → ${version})`)

        // 备份旧数据（如果需要迁移）
        const oldVersion = event.oldVersion
        if (oldVersion > 0 && oldVersion < version) {
          console.log(`[IndexedDB] 执行数据迁移: ${oldVersion} → ${version}`)
          executeDataMigration(db, oldVersion, version)
        }

        // 创建或更新存储对象和索引
        Object.entries(stores).forEach(([storeName, storeConfig]) => {
          if (!db.objectStoreNames.contains(storeName)) {
            // 创建新存储
            const store = db.createObjectStore(storeName, {
              keyPath: storeConfig.keyPath || 'id',
              autoIncrement: storeConfig.autoIncrement !== false
            })

            // 创建索引
            if (storeConfig.indexes) {
              storeConfig.indexes.forEach((index) => {
                store.createIndex(index.name, index.keyPath, index.options || {})
                console.log(`[IndexedDB] 创建索引: ${storeName}.${index.name}`)
              })
            }

            console.log(`[IndexedDB] 创建存储: ${storeName}`)
          } else {
            // 存储已存在，在版本变更事务中直接获取存储对象
            // 注意：在 onupgradeneeded 中不能使用 db.transaction()
            // 而是使用 event.currentTarget.transaction.objectStore()
            const transaction = event.currentTarget.transaction
            const store = transaction.objectStore(storeName)

            if (storeConfig.indexes) {
              storeConfig.indexes.forEach((index) => {
                if (!store.indexNames.contains(index.name)) {
                  store.createIndex(index.name, index.keyPath, index.options || {})
                  console.log(`[IndexedDB] 更新索引: ${storeName}.${index.name}`)
                }
              })
            }
          }
        })
      }

      request.onsuccess = (event) => {
        db.value = event.target.result
        isConnected.value = true
        isInitializing.value = false
        error.value = null
        console.log(`[IndexedDB] 连接成功: ${dbName} (版本 ${version})`)

        // 验证所有索引是否存在
        validateDatabaseIntegrity()
          .then(() => {
            console.log(`[IndexedDB] 数据库完整性验证通过`)
            resolve(db.value)
          })
          .catch((validationError) => {
            console.error(`[IndexedDB] 数据库完整性验证失败: ${validationError.message}`)
            handleDatabaseError(validationError).then(resolve).catch(reject)
          })
      }

      request.onerror = (event) => {
        isInitializing.value = false
        error.value = `数据库连接失败: ${event.target.error}`
        console.error(`[IndexedDB] 错误: ${error.value}`)
        reject(error.value)
      }

      request.onblocked = () => {
        console.warn(`[IndexedDB] 数据库被阻塞，请关闭其他打开的连接`)
        // 尝试关闭所有其他连接
        handleDatabaseBlocked().then(resolve).catch(reject)
      }
    })

    return pendingInitPromise
  }

  // 数据迁移逻辑（可根据需要扩展）
  const executeDataMigration = (db, fromVersion, toVersion) => {
    // 这里可以添加具体的迁移逻辑
    // 例如：从旧版本的数据结构迁移到新版本
    console.log(`[IndexedDB] 执行默认数据迁移: ${fromVersion} → ${toVersion}`)

    // 示例：如果从版本1迁移到2，可以添加以下逻辑
    if (fromVersion < 2 && toVersion >= 2) {
      // 示例：为已有的用户添加默认设置
      if (db.objectStoreNames.contains('users')) {
        const transaction = db.transaction('users', 'readwrite')
        const store = transaction.objectStore('users')

        // 这里可以遍历所有用户并添加新字段
        const cursorRequest = store.openCursor()
        cursorRequest.onsuccess = (event) => {
          const cursor = event.target.result
          if (cursor) {
            const user = cursor.value
            user.settings = { theme: 'light', notifications: true }
            store.put(user)
            cursor.continue()
          }
        }
      }
    }

    // 可以添加更多版本迁移逻辑...
  }

  // 验证数据库完整性（存储和索引）
  const validateDatabaseIntegrity = () => {
    return new Promise((resolve, reject) => {
      if (!isConnected.value) {
        return initializeDB().then(validateDatabaseIntegrity).then(resolve).catch(reject)
      }

      try {
        let allValid = true
        const validationErrors = []

        // 验证存储和索引
        Object.entries(stores).forEach(([storeName, storeConfig]) => {
          if (!db.value.objectStoreNames.contains(storeName)) {
            allValid = false
            validationErrors.push(`存储 ${storeName} 不存在`)
            return
          }

          // 验证索引
          if (storeConfig.indexes) {
            storeConfig.indexes.forEach((index) => {
              try {
                const transaction = db.value.transaction(storeName, 'readonly')
                const store = transaction.objectStore(storeName)

                if (!store.indexNames.contains(index.name)) {
                  allValid = false
                  validationErrors.push(`索引 ${storeName}.${index.name} 不存在`)
                }
              } catch (err) {
                allValid = false
                validationErrors.push(`验证索引 ${storeName}.${index.name} 失败: ${err.message}`)
              }
            })
          }
        })

        if (allValid) {
          resolve(true)
        } else {
          reject(new Error(`数据库完整性检查失败: ${validationErrors.join('; ')}`))
        }
      } catch (err) {
        reject(new Error(`数据库完整性验证错误: ${err.message}`))
      }
    })
  }

  // 处理数据库错误（如索引缺失）
  const handleDatabaseError = (error) => {
    console.log(`[IndexedDB] 尝试修复数据库错误: ${error.message}`)

    // 如果是索引缺失错误，尝试重建索引
    if (error.message.includes('不存在')) {
      return rebuildDatabase().then(() => {
        console.log(`[IndexedDB] 数据库修复成功`)
        return initializeDB()
      })
    }

    return Promise.reject(error)
  }

  // 处理数据库阻塞
  const handleDatabaseBlocked = () => {
    return new Promise((resolve, reject) => {
      // 尝试关闭数据库并重新连接
      if (db.value) {
        db.value.close()
        isConnected.value = false
      }

      // 等待一段时间后重试
      setTimeout(() => {
        initializeDB().then(resolve).catch(reject)
      }, 1000)
    })
  }

  // 重建数据库（删除并重新创建）
  const rebuildDatabase = () => {
    return new Promise((resolve, reject) => {
      console.log(`[IndexedDB] 准备重建数据库: ${dbName}`)

      if (db.value) {
        db.value.close()
        isConnected.value = false
      }

      const deleteRequest = indexedDB.deleteDatabase(dbName)

      deleteRequest.onsuccess = () => {
        console.log(`[IndexedDB] 旧数据库已删除，准备重新创建`)
        resolve(true)
      }

      deleteRequest.onerror = (event) => {
        reject(new Error(`删除数据库失败: ${event.target.error}`))
      }

      deleteRequest.onblocked = () => {
        reject(new Error(`删除数据库被阻塞，请关闭其他连接`))
      }
    })
  }

  // 执行事务操作（自动初始化）
  const executeTransaction = (storeName, mode, callback, indexName = null) => {
    return initializeDB().then(() => {
      try {
        const transaction = db.value.transaction(storeName, mode)
        const store = transaction.objectStore(storeName)
        const result = callback(store)

        return new Promise((resolve, reject) => {
          transaction.oncomplete = () => resolve(result)
          transaction.onerror = () => reject(transaction.error)
        })
      } catch (err) {
        return Promise.reject(err)
      }
    })
  }

  // 添加/更新数据
  const putData = (storeName, data) => {
    return executeTransaction(storeName, 'readwrite', (store) => {
      if (Array.isArray(data)) {
        data.forEach((item) => store.put(item))
      } else {
        store.put(data)
      }
    })
  }

  // 根据索引查询数据
  const queryByIndex = (storeName, indexName, queryValue) => {
    return executeTransaction(
      storeName,
      'readonly',
      (store) => {
        const index = store.index(indexName)
        const request = index.getAll(queryValue)

        return new Promise((resolve, reject) => {
          request.onsuccess = () => resolve(request.result || [])
          request.onerror = () => reject(request.error)
        })
      },
      indexName
    )
  }

  // 获取所有数据
  const getAllData = (storeName) => {
    const data = reactive([])

    const fetchData = () => {
      executeTransaction(storeName, 'readonly', (store) => {
        const request = store.getAll()
        request.onsuccess = () => {
          const result = request.result || []
          data.splice(0, data.length, ...result)
        }
      }).catch((err) => {
        error.value = err
        console.error(`[IndexedDB] 获取数据失败: ${err.message}`)
      })
    }

    initializeDB().then(fetchData)

    return data
  }

  // 根据ID获取数据
  const getDataById = (storeName, id) => {
    return executeTransaction(storeName, 'readonly', (store) => {
      const request = store.get(id)
      return new Promise((resolve, reject) => {
        request.onsuccess = () => resolve(request.result)
        request.onerror = () => reject(request.error)
      })
    })
  }

  // 根据ID删除数据
  const deleteData = (storeName, id) => {
    return executeTransaction(storeName, 'readwrite', (store) => {
      store.delete(id)
    })
  }

  // 清空存储对象
  const clearStore = (storeName) => {
    return executeTransaction(storeName, 'readwrite', (store) => {
      store.clear()
    })
  }

  // 关闭数据库连接
  const closeDB = () => {
    if (db.value) {
      db.value.close()
      isConnected.value = false
      console.log(`[IndexedDB] 连接已关闭: ${dbName}`)
    }
  }

  // 监听组件卸载，自动关闭连接
  watchEffect((onCleanup) => {
    onCleanup(() => closeDB())
  })

  // 获取数据库信息
  const getDatabaseInfo = () => ({
    name: dbName,
    version,
    stores: Object.keys(stores),
    isConnected: isConnected.value,
    lastError: error.value
  })

  return {
    isConnected,
    error,
    putData,
    queryByIndex,
    getAllData,
    getDataById,
    deleteData,
    clearStore,
    closeDB,
    initializeDB,
    validateDatabaseIntegrity,
    getDatabaseInfo
  }
}
